package com.common.redis.service.impl;

import com.common.redis.service.IRedisOperationService;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.concurrent.TimeUnit;

/**
 * @auther WuJun.Zhang
 * @date 2022/3/1 上午10:24
 */
@Component
public class RedisOperationServiceImpl<T> implements IRedisOperationService<T> {

    @Resource
    private RedisTemplate<String, T> redisTemplate;

    @Override
    public T get(String key) {
        return redisTemplate.opsForValue().get(key);
    }

    @Override
    public void put(String key, T value) {
        redisTemplate.opsForValue().set(key, value);
    }

    @Override
    public void put(String key, T value, long expires) {
        redisTemplate.opsForValue().set(key, value, expires, TimeUnit.SECONDS);
    }

    @Override
    public void delete(String key) {
        redisTemplate.delete(key);
    }

    @Override
    public long set(String key, T value, int expires) {
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        String LOCK_SCRIPT_PATH = "lua/redis-lock.lua";
        redisScript.setLocation(new ClassPathResource(LOCK_SCRIPT_PATH));
        redisScript.setResultType(Long.class);
        Long result = redisTemplate.execute(redisScript, Collections.singletonList(key), expires, value);
        return null == result ? 0 : result;
    }

    @Override
    public boolean delete(String key, T value, int expires) {
        DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();
        String UNLOCK_SCRIPT_PATH = "lua/redis-unlock.lua";
        redisScript.setLocation(new ClassPathResource(UNLOCK_SCRIPT_PATH));
        redisScript.setResultType(Long.class);
        Object result = redisTemplate.execute(redisScript, Collections.singletonList(key), expires, value);
        return Long.valueOf(1).equals(result);
    }

    @Override
    public Long getExpires(String key) {
        return redisTemplate.opsForValue().getOperations().getExpire(key);
    }
}
